//
// Created by Administrator on 2025/8/22.
//

#include <gtest/gtest.h>
#include "../material/StrBlob.h"


TEST(ch12, fwoje)
{
    // {
    //     //p
    //     std::shared_ptr< std::string> p1 = std::make_shared<std::string>("");
    //     // if p1 is not null, check whether it's the empty string
    //     if (p1 && p1->empty())
    //         *p1 = "hi"; // if so, dereference p1 to assign a new value to that string
    //
    //     // std::cout << *p1 << std::endl;
    // }
    // {
    //
    //     // shared_ptr that points to an int with value 42
    //     std::shared_ptr<int> p3 = std::make_shared<int>(42);
    //     // p4 points to a string with value 9999999999
    //     std::shared_ptr<std::string> p4 = std::make_shared<std::string>(10, '9');
    //     // p5 points to an int that is value initialized to 0
    //     std::shared_ptr<int> p5 = std::make_shared<int>();
    // }
    //
    // {
    //     // use auto
    //     // p6 points to a dynamically allocated, empty vector<string>
    //     auto p6 = std::make_shared<std::vector<std::string>>();
    // }
    //
    // {
    //     auto p = std::make_shared<int>(42); // object to which p points has one user
    //     auto q(p); // p and q point to the same object
    //     // object to which p and q point has two users
    // }

    // {
    //     auto r = std::make_shared<int>(10);
    //     auto q = std::make_shared<int>(2);
    //     r = q;
    //     std::cout << r.use_count() << std::endl;
    //     std::cout << q.use_count() << std::endl;
    // }

    // {
    //     int *pi = new int;
    //     std::cout << *pi << std::endl;//pi是未初始化/默认初始化
    // }
    // {
    //     // 用()值初始化
    //     std::string* ps1 = new std::string; // default initialized to the empty string
    //     std::string* ps = new std::string(); // value initialized to the empty string
    //     int* pi1 = new int; // default initialized; *pi1 is undefined
    //     int* pi2 = new int(); // value initialized to 0; *pi2 is 0
    //     std::cout << *pi2 << std::endl;
    // }

    {
        //std::bad_alloc
        // int *p1 = new int[100000000000000];
    }
    {
        // ok: it is always ok to delete a null pointer
        int* p = nullptr;
        delete p;
    }

    {
        std::shared_ptr<double> p1; // shared_ptr that can point at a double
        std::shared_ptr<int> p2(new int(42)); // p2 points to an int with value 42
    }
    {
        // std::shared_ptr<int> p1 = new int(42);
        std::shared_ptr<int> p2(new int(42));
    }
    {
        //<html>无法将类型 int* 的右值转换为返回值类型 std::shared_ptr&lt;int&gt;，<br/>因为构造函数 shared_ptr&lt;typename _Yp&gt;(_Yp* __p) 为显式
        // auto clone1 = [](int p)-> std::shared_ptr<int>
        // {
        //     return new int(p);
        // };

        // auto clone2 = [](int p)-> std::shared_ptr<int>
        // {
        //     return std::shared_ptr<int>(new int(p));
        // };
        // auto pi = clone2(2);
        // std::cout << *pi << std::endl;
    }
    // {
    //     auto process = [](std::shared_ptr<int> p) {return;};
    //     int *x(new int(1024)); // dangerous: x is a plain pointer, not a smart pointer
    //     // process(x); // error: cannot convert int* to shared_ptr<int>
    //     process(std::shared_ptr<int>(x)); // legal, but the memory will be deleted!
    //     int j = *x; // undefined: x is a dangling pointer!
    // }

    {
        // auto sp = std::make_shared<int>();
        // auto p = sp.get();
        // delete p;//会错误
    }
}

TEST(ch12, exercise1201)
{
    StrBlob b1;
    {
        StrBlob b2 = {"a", "an", "the"};
        b1 = b2;
        b2.push_back("about");
    }
    std::cout << b1.size() << std::endl; //4
}

TEST(ch12, exericse1202)
{
    //参考StrBlob.h StrBlob.cpp
    StrBlob b1 = {"hello", "world", "c++"};
}

TEST(ch12, iofi)
{
    {
        typedef int arrT[42]; // arrT names the type array of 42 ints
        int* p = new arrT; // allocates an array of 42 ints; p points to the first one
        using arrrT = int[32];
        int* p2 = new arrrT;
        // for (int i = 0; i < 42; i++)
        // {
        //     std::cout << p[i] << std::endl;
        // }
    }
    {
        int* pia = new int[10]; // block of ten uninitialized ints
        int* pia2 = new int[10](); // block of ten ints value initialized to 0
        std::string* psa = new std::string[10]; // block of ten empty strings
        std::string* psa2 = new std::string[10](); // block of ten empty strings
        // for (int i = 0; i < 10; i++)
        // {
        //     std::cout << pia2[i] << std::endl;
        // }
        // block of ten ints each initialized from the corresponding initializer
        int *pia3 = new int[10]{0,1,2,3,4,5,6,7,8,9};
        // block of ten strings; the first four are initialized from the given initializers
        // remaining elements are value initialized
        std::string *psa3 = new std::string[10]{"a", "an", "the", std::string(3,'x')};
        // int *pia4 = new int[10]{0,1,2,3,4,5,6,7,8,9, 10};
        int *pia5 = new int[10]{0,1,2,3,4};
        // for (int i = 0; i < 10; i++)
        // {
        //     // std::cout << psa3[i] << std::endl;
        //     // std::cout << pia3[i] << std::endl;
        //     std::cout << pia5[i] << std::endl;
        // }
    }

    // {
    //     auto get_size = []{return 0;};
    //     size_t n = get_size(); // get_size returns the number of elements needed
    //     int* p = new int[n]; // allocate an array to hold the elements
    //     for (int* q = p; q != p + n; ++q)
    //         /* process the array */ ;
    // }
    //
    // {
    //     char arr[0];
    //     std::cout << sizeof(arr) << std::endl;
    //     char *p = new char[0];
    // }
    //
    // {
    //     // up points to an array of ten uninitialized ints
    //     std::unique_ptr<int[]> up(new int[10]);
    //     // up.reset(); // automatically uses delete[] to destroy its pointer
    //     for (size_t i = 0; i != 10; ++i)
    //         up[i] = i; // assign a new value to each of the elements
    // }
    //
    // {
    //     // to use a shared_ptr we must supply a deleter
    //     std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
    //     sp.reset(); // uses the lambda we supplied that uses delete[] to free the array
    //
    //     // shared_ptrs don't have subscript operator and don't support pointer arithmetic
    //     for (size_t i = 0; i != 10; ++i)
    //         *(sp.get() + i) = i; // use get to get a built-in pointer
    // }

    {
        std::allocator<std::string> alloc; // object that can allocate strings
        auto const p = alloc.allocate(10); // allocate n unconstructed strings
        auto q = p;
        std::allocator_traits<decltype(alloc)>::construct(alloc, q++, "hello");
        std::allocator_traits<decltype(alloc)>::construct(alloc, q++, 10, 'c');
        std::allocator_traits<decltype(alloc)>::construct(alloc, q++);
        for (auto q = p; q != p + 3; ++q)
        {
            // std::cout << *q << std::endl;
        }
        while (q != p)
            std::allocator_traits<decltype(alloc)>::destroy(alloc, --q);
        alloc.deallocate(p, 10);
    }

    {
        std::vector<int> vi{1,2,3,4,5,6,7,8,9};
        std::allocator<int> alloc;
        // allocate twice as many elements as vi holds
        auto p = alloc.allocate(vi.size() * 2);
        // construct elements starting at p as copies of elements in vi
        auto q = uninitialized_copy(vi.begin(), vi.end(), p);
        // initialize the remaining elements to 42
        std::uninitialized_fill_n(q, vi.size(), 42);
        for (auto q = p; q != p + vi.size() * 2; ++q)
        {
            std::cout << *q << std::endl;
        }
    }
}

TEST(ch12, exercise1223)
{
    // auto comcatenate_str = []()
}